package com.philosophy.web.repository.impl;

import com.philosophy.web.domain.generate.AbstractGenerateShortUrl;
import com.philosophy.web.domain.generate.RoutingDB;
import com.philosophy.web.domain.generate.UrlMapping;
import com.philosophy.web.mapper.UrlMappingMapper;
import com.philosophy.web.repository.ShortUrlRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import static com.philosophy.constant.RedisConstant.COUNT_KEY_FORMAT;

/**
 * @author philosophy
 */
@Repository
@Slf4j
public class ShortUrlRepositoryImpl implements ShortUrlRepository {
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource(name = "generateShortUrlBySnow")
    AbstractGenerateShortUrl generateShortUrl;
    @Resource
    private UrlMappingMapper urlMappingMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UrlMapping save(String originUrl) {
        UrlMapping urlMapping = generateShortUrl.generateShortUrl(originUrl);
        return createUrlMapping(urlMapping);
    }

    /**
     * 创建长url和短url的映射关系
     *
     * @param urlMapping url映射关系
     * @return ShortUrl
     */
    private UrlMapping createUrlMapping(UrlMapping urlMapping) {
        //数据库路由编号
        int databaseNum = RoutingDB.getDatabaseNum(urlMapping.getShortUrl());

        long start = System.currentTimeMillis();
        //持久化到数据库
        urlMappingMapper.insert(urlMapping);
        //持久化到redis
        // 由于没有这么多的服务器,这里使用redis的hash 的数据结构模拟多个数据库的情形
        String key = String.format(COUNT_KEY_FORMAT, databaseNum);
        redisTemplate.opsForHash().put(key, urlMapping.getShortUrl(), urlMapping);
        long end = System.currentTimeMillis();
        log.info("createUrlMapping总耗时:" + (end - start) + "ms");
        return urlMapping;
    }
}
